/**
 * @Author：zy
 * @Description：初始化虚拟dom节点  即根据虚拟DOM节点 => 创建真实的DOM节点
 * @Data: 2020/10/10 15:40
 */
export default function initVNode(vnode){
    //获取虚拟dom节点类型
    let {vtype} = vnode;

    //不存在
    if(!vtype){
        return document.createTextNode(vnode);
    }

    //如果是html标签
    if(vtype === 1){
        return createElement(vnode)}

    //如果是class组件
    if(vtype === 2){
        return createClassComp(vnode);
    }

    //如果是函数组件
    if(vtype === 3){
        return createFuncComp(vnode);
    }
}


//创建标签对应的DOM节点
function createElement(vnode) {
    console.log('虚拟DOM节点,标签',vnode);
    const {type,props} = vnode;
    const {children,...rest} = props;
    const node = document.createElement(type);
    Object.keys(rest).forEach(key => {
        if(key === 'className'){
            node.setAttribute('class',rest[key]);
        }else {
            node.setAttribute(key, rest[key]);
        }
    });

    //子元素
    children.forEach(child => {
        node.appendChild(initVNode(child));
    });
    return node;
}

//创建类组件对应的DOM节点
function createClassComp(vnode) {
    console.log('虚拟DOM节点,类组件',vnode);

    const {type,props} = vnode;
    const {children,...rest} = props;

    //创建对象实例
    const comp = new type(rest);

    //执行类组件render方法 得到新的虚拟DOM节点
    const newVNode = comp.render();

    return initVNode(newVNode);
}

//创建函数组件对应的DOM节点
function createFuncComp(vnode) {
    console.log('虚拟DOM节点,函数组件',vnode);

    const {type,props} = vnode;
    const {children,...rest} = props;

    //执行函数组件方法 得到新的虚拟DOM节点
    const newVNode = type(rest);

    return initVNode(newVNode);
}